#ifndef __viewwin
#define __viewwin

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <console.h>

extern console cons;

struct badviewport {};
struct viewport {

	int xmax, ymax;

	viewport (const string& name, int width, int height, int depth=32) {
		xmax = width - 1;
		ymax = height - 1;
		SDL_Init (SDL_INIT_VIDEO);
		SDL_Surface* s = SDL_SetVideoMode (width, height, depth, SDL_OPENGL | SDL_RESIZABLE);
		if (s) {
			cout << "viewport initialised : " << name << " " << width << " " << height << " " << depth << endl;
			SDL_WM_SetCaption (name.c_str (), name.c_str());
			glViewport (0, 0, width, height);
			cons.set_window (box<int>(0, -ymax, xmax, 0));
		}
		else
			throw badviewport();
	}
};


//
// window
//

class window : public box<double> {

	double pan_x, pan_y;

	static const double pan_scale = 0.002;
	static const double zoom_scale = 0.002;

	void calc_panxy () {
		pan_x = pan_scale * width;
		pan_y = pan_scale * height;
	}

	public:

		window (double left, double right, double bottom, double top) :
			box<double> (left, right, bottom, top) {
				calc_panxy ();
			}

		void panx (int dir) {
			left = left + pan_x * dir;
			right = left + width;
		}

		void pany (int dir) {
			bottom = bottom + pan_y * dir;
			top = bottom + height;
		}

		void zoom (int dir) {

			double aspect_ratio = width / height;

			double dw = zoom_scale * width * dir, dh = dw / aspect_ratio, dw2 = dw / 2, dh2 = dh / 2;
			double l = left - dw2;
			double r = right + dw2;
			double b = bottom - dh2;
			double t = top + dh2;
			double w = r - l, h = t - b;
			if ((w > 0) && (h > 0)) {
				left = l;
				right = r;
				bottom = b;
				top = t;
				width = right - left;
				height = top - bottom;
				calc_panxy ();
			}

		}

		void project () {

			glMatrixMode (GL_PROJECTION);
			glLoadIdentity ();
			glOrtho (left, right, bottom, top, 0, 1);
			glMatrixMode (GL_MODELVIEW);

		}


};

template <typename S, typename T> inline void view2win (S vx, S vy, T& wx, T& wy, viewport& view, window& win) {

	double xr = vx * 1. / view.xmax;
	double yr = 1 - vy * 1. / view.ymax;

	wx = (T) (win.left + xr * win.width);
	wy = (T) (win.bottom + yr * win.height);

}
#endif
